import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;


public class Server {
    private ServerSocketChannel ssc;
    private Selector selector;
    private static final int PORT = 9999;

    private static ConcurrentHashMap<String,SocketChannel> map = new ConcurrentHashMap<>();

    public Server(){

    }

    public void init() throws Exception{
        ssc = ServerSocketChannel.open();
        //设置非阻塞
        ssc.configureBlocking(false);
        ssc.bind(new InetSocketAddress(PORT));

        selector = Selector.open();
        //设置选择器监听接收客户端事件
        ssc.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void start() {
        MsgHandle msgHandle = new MsgHandle();
        while (true){
            Iterator<SelectionKey> iterator = null;
            SocketChannel socketChannel = null;
            try {
                while (selector.select() > 0){ //select方法会阻塞，直到监听事件触发
                    iterator = selector.selectedKeys().iterator();

                    while (iterator.hasNext()){
                        SelectionKey sk = iterator.next();
                        if (sk.isAcceptable()){//触发的是客户端连接事件
                            socketChannel = ssc.accept();
                            socketChannel.configureBlocking(false);//客户端管道设置为非阻塞
                            socketChannel.register(selector,SelectionKey.OP_READ);

                        }else if(sk.isReadable()){
                            socketChannel = (SocketChannel)sk.channel();
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            int len = 0;
                            String msg = "";
                            while ((len = socketChannel.read(buffer))>0){
                                buffer.flip();
                                msg += new String(buffer.array(),0,len);

                                buffer.clear();
                            }
                            System.out.println("����˽��յ���Ϣ "+msg);
                            if (msg.contains("1!@#")){
                                //注册昵称
                                map.put(msg.substring(msg.indexOf("!@#")+3,msg.length()),socketChannel);
                                //注册成功后向访问者返回聊天室成员
                                msgHandle.sentMemberInfo(socketChannel,map);
                            }else if(msg.contains("@!#")){
                                //私聊
                                msgHandle.sentToOne(map,sk,msg);
                            }else if(msg.contains("#@!")){
                                //群发
                                msgHandle.sendToAll(map,sk,msg);
                            }

                        }
                        //处理完事件需要移除事件(管道如果有消息会重新触发，所以可以使用完就移除)
                        iterator.remove();
                    }
                }
            }catch (Exception e){
                e.printStackTrace();

                Iterator<SocketChannel> sIterator =map.values().iterator();
                while (sIterator.hasNext()) {
                    SocketChannel value = sIterator.next();
                    // 当客户端断开连接的时候  对应的要把存储用户集合 删除
                    if (value == socketChannel) {
                        sIterator.remove();
                    }else{
                        //客户端断开连接时 需要通知其他成员下线
                        msgHandle.sentMemberInfo(socketChannel,map);
                    }
                }


                if (iterator != null){
                    iterator.remove();
                }
                //客户端断开连接时候  需要对管道关闭
                if (socketChannel!=null){
                    try {
                        socketChannel.close();
                    }catch (Exception ee){
                        ee.printStackTrace();
                    }

                }
            }

        }

    }
}
